/*
 * Copyright (c) 2023-2023 elsfs Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.elsfs.cloud.common.excel.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.support.ExcelTypeEnum;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;
import org.springframework.core.io.InputStreamSource;

/**
 * 导出 导入excel 处理
 *
 * @param <E> 数据类型
 * @author zeng
 */
public interface ExcelUploadController<E> {

  /**
   * 处理excel上传
   *
   * @param uploadFile 上传的文件
   * @param headClass 类型
   * @param readListener 处理的监听器
   * @return data
   * @throws Exception e
   */
  default List<E> importExcel(
      InputStreamSource uploadFile, Class<E> headClass, ReadListener<?> readListener)
      throws Exception {
    if (Objects.isNull(uploadFile)) {
      throw new RuntimeException("uploadFile null or file name null");
    }
    return EasyExcel
        // 读取文件 处理的类型 箭头
        .read(uploadFile.getInputStream(), headClass, readListener)
        .sheet()
        .head(headClass)
        .doReadSync();
  }

  /**
   * 导出excel
   *
   * @param listData 数据
   * @param response response
   * @param fileName 文件名
   * @param headClass 类型
   * @throws IOException 异常
   */
  default void exportXls(
      List<E> listData, HttpServletResponse response, String fileName, Class<E> headClass)
      throws IOException {
    setExcelResponseProp(response, fileName);
    EasyExcel.write(response.getOutputStream())
        // 在 write 方法之后， 在 sheet方法之前都是设置WriteWorkbook的参数
        .head(headClass)
        .excelType(ExcelTypeEnum.XLSX)
        .sheet()
        .doWrite(listData);
  }

  /**
   * 设置响应结果
   *
   * @param response 响应结果对象
   * @param rawFileName 文件名
   * @throws UnsupportedEncodingException 不支持编码异常
   */
  private void setExcelResponseProp(HttpServletResponse response, String rawFileName)
      throws UnsupportedEncodingException {
    response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    response.setCharacterEncoding("utf-8");
    String fileName =
        URLEncoder.encode(rawFileName, StandardCharsets.UTF_8).replaceAll("\\+", "%20");
    response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
  }
}
